

namespace gen {

	///////////////////////////////////////////////////////////////////////////
    //
    //  Generic generate function implementation
    //
    ///////////////////////////////////////////////////////////////////////////
	#include <boost/preprocessor/punctuation/comma_if.hpp>
	#include <boost/preprocessor/repetition/enum_params.hpp>

	#ifndef GENE_MAX_SIZE
	#  define GENE_MAX_SIZE 5
	#endif

	#define GENE_size(z, n, unused)								\
	  template <class CharT,									\
				BOOST_PP_ENUM_PARAMS(n, class RangeT)			\
				BOOST_PP_COMMA_IF(n)							\
				class DerivedT,									\
				class IteratorT>								\
	  inline typename generator_string< CharT >::str_type		\
	  generate(IteratorT const& first, IteratorT const& last,	\
			   generator<DerivedT> const& g)					\
	  {															\
		typedef typename create_context_t< CharT,				\
					  BOOST_PP_CAT(mpl::vector,BOOST_PP_INC(n))<\
							range<IteratorT>					\
							BOOST_PP_COMMA_IF(n)				\
        					BOOST_PP_ENUM_PARAMS(n,RangeT)		\
							>									\
				>::context_t context_t;							\
		context_t context = context_t(first,last);				\
		g.derived().generate(context);							\
		return context.str();									\
	  }															\
																\
	  template <class CharT,									\
				BOOST_PP_ENUM_PARAMS(n, class RangeT)			\
				BOOST_PP_COMMA_IF(n)							\
				class DerivedT,									\
				class IteratorT>								\
	  inline typename generator_string< CharT >::str_type		\
	  generate(IteratorT const& first, IteratorT const& last,	\
			   typename generator_string<CharT>::str_type const& buf,	\
			   generator<DerivedT> const& g)					\
	  {															\
		typedef create_context_t< CharT,						\
					  BOOST_PP_CAT(mpl::vector,BOOST_PP_INC(n))<\
							range<IteratorT>					\
							BOOST_PP_COMMA_IF(n)				\
        					BOOST_PP_ENUM_PARAMS(n,RangeT)		\
							>									\
					  > create_t;								\
		typedef typename create_t::context_t		context_t;	\
		typedef typename create_t::context_nil_t	context_nil_t;		\
		context_t context = context_t(first,last,context_nil_t(buf));	\
		g.derived().generate(context);							\
		return context.str();									\
	  }															\
																\
	  template <class CharT,									\
				BOOST_PP_ENUM_PARAMS(n, class RangeT)			\
				BOOST_PP_COMMA_IF(n)							\
				class DerivedT,									\
				class IteratorT>								\
	  inline typename generator_string< CharT >::str_type		\
	  generate(IteratorT const& current, IteratorT const& first,	\
			   IteratorT const& last, generator<DerivedT> const& g)	\
	  {															\
		typedef typename create_context_t< CharT,				\
					  BOOST_PP_CAT(mpl::vector,BOOST_PP_INC(n))<\
							range<IteratorT>					\
							BOOST_PP_COMMA_IF(n)				\
        					BOOST_PP_ENUM_PARAMS(n,RangeT)		\
							>									\
				>::context_t context_t;							\
		context_t context = context_t(first,last);				\
	    context.current(current);								\
		g.derived().generate(context);							\
		return context.str();									\
	  }															\
																\
	  template <class CharT,									\
				BOOST_PP_ENUM_PARAMS(n, class RangeT)			\
				BOOST_PP_COMMA_IF(n)							\
				class DerivedT,									\
				class DataT>									\
	  inline typename generator_string< CharT >::str_type		\
	  generate(data_wrapper<DataT> const& data,					\
			   generator<DerivedT> const& g)					\
	  {															\
		return generate<CharT									\
						BOOST_PP_COMMA_IF(n)					\
        				BOOST_PP_ENUM_PARAMS(n,RangeT)			\
					   >(data.begin(), data.end(), g);			\
	  }								
									

	#include <boost/preprocessor/iteration/local.hpp>

	#define BOOST_PP_LOCAL_MACRO(n)   GENE_size(~, n, ~)
	#define BOOST_PP_LOCAL_LIMITS     (0, GENE_MAX_SIZE - 1)
	#include BOOST_PP_LOCAL_ITERATE()

}
